<template>
  <div class="searchable-select">
    <el-select
      v-model="selectedValue"
      :filterable="searchable"
      :remote="remote"
      :remote-method="remoteMethod"
      :loading="loading"
      :clearable="clearable"
      :placeholder="placeholder"
      :popper-class="['custom-select-dropdown']"
      @change="handleChange"
      @visible-change="handleVisibleChange"
    >
      <template #prefix>
        <el-icon :size="16" class="search-icon">
          <Search />
        </el-icon>
      </template>
      <el-option
        v-for="item in filteredOptions"
        :key="item.resId"
        :label="item.resName"
        :value="item.resId"
        :class="{ 'highlight-option': highlightMatches && searchQuery }"
      >
        <slot name="option" :item="item" :query="searchQuery">
          <span v-if="highlightMatches && searchQuery" v-html="highlightText(item.resName, searchQuery)"></span>
          <span v-else>{{ item.resName }}</span>
          <span v-if="item.tag" class="option-tag" :style="{ backgroundColor: item.tagColor }">
            {{ item.tag }}
          </span>
        </slot>
      </el-option>
      
      <template #empty>
        <div class="empty-content">
          <el-icon :size="24" class="empty-icon">
            <FolderDelete />
          </el-icon>
          <p>{{ emptyText || '无匹配数据' }}</p>
        </div>
      </template>
    </el-select>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { Search, FolderDelete } from '@element-plus/icons-vue'

interface filteredOptions {
  resId: string | number
  resName: string
}

const props = defineProps({
  modelValue: [String, Number, Array],
  options: {
    type: Array<filteredOptions>,
    default: () => []
  },
  placeholder: {
    type: String,
    default: '请选择'
  },
  searchable: {
    type: Boolean,
    default: true
  },
  remote: {
    type: Boolean,
    default: false
  },
  remoteMethod: {
    type: Function,
    default: null
  },
  clearable: {
    type: Boolean,
    default: true
  },
  loading: {
    type: Boolean,
    default: false
  },
  emptyText: String,
  highlightMatches: {
    type: Boolean,
    default: true
  },
})

const emit = defineEmits(['update:modelValue', 'change', 'visible-change'])

const selectedValue = ref(props.modelValue)
const searchQuery = ref('')
const isOpen = ref(false)

// 过滤选项
const filteredOptions:any = computed(() => {
  if (!props.searchable || !searchQuery.value || props.remote) {
    return props.options
  }
  
  const query = searchQuery.value.toLowerCase()
  return props.options.filter(item => 
    item.resName.toLowerCase().includes(query) ||
    String(item.resId).toLowerCase().includes(query)
  )
})

// 高亮匹配文本
const highlightText = (text, query) => {
  const lowerText = text.toLowerCase()
  const lowerQuery = query.toLowerCase()
  const index = lowerText.indexOf(lowerQuery)
  
  if (index === -1) return text
  
  const before = text.substring(0, index)
  const match = text.substring(index, index + query.length)
  const after = text.substring(index + query.length)
  
  return `${before}<span class="highlight">${match}</span>${after}`
}

// 处理值变化
const handleChange = (value) => {
  emit('update:modelValue', value)
  emit('change', value)
}

// 处理下拉框显示状态变化
const handleVisibleChange = (visible) => {
  isOpen.value = visible
  emit('visible-change', visible)
  if (!visible) {
    searchQuery.value = ''
  }
}

// 监听外部 modelValue 变化
watch(() => props.modelValue, (val) => {
  selectedValue.value = val
})

// 远程搜索方法
const remoteMethod = (query) => {
  searchQuery.value = query
  if (props.remoteMethod) {
    props.remoteMethod(query)
  }
}
</script>

<style lang="scss" scoped>
.searchable-select {
  width: 100%;
  
  :deep(.el-select) {
    .el-input__wrapper {
      padding-left: 10px;
      border-radius: 8px;
      box-shadow: 0 0 0 1px var(--el-border-color);
      transition: all 0.3s ease;
      
      &:hover {
        box-shadow: 0 0 0 1px var(--el-color-primary);
      }
      
      &.is-focus {
        box-shadow: 0 0 0 1px var(--el-color-primary);
      }
    }
    
    .el-input__inner {
      padding-left: 8px;
    }
    
    .search-icon {
      color: var(--el-text-color-placeholder);
      transition: all 0.3s;
    }
    
    &:hover .search-icon {
      color: var(--el-color-primary);
    }
  }
}

// 下拉菜单样式
:deep(.custom-select-dropdown) {
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
  border: none;
  padding: 8px 0;
  
  .el-select-dropdown__item {
    height: 40px;
    padding: 0 16px;
    font-size: 14px;
    color: var(--el-text-color-regular);
    display: flex;
    align-items: center;
    justify-content: space-between;
    
    &:hover {
      background-color: var(--el-color-primary-light-9);
    }
    
    &.selected {
      color: var(--el-color-primary);
      font-weight: 500;
    }
    
    &.highlight-option {
      font-weight: normal;
    }
    
    .highlight {
      color: var(--el-color-primary);
      font-weight: bold;
    }
    
    .option-tag {
      font-size: 12px;
      padding: 2px 6px;
      border-radius: 4px;
      color: white;
      margin-left: 8px;
    }
  }
  
  .empty-content {
    padding: 16px;
    text-align: center;
    color: var(--el-text-color-secondary);
    
    .empty-icon {
      margin-bottom: 8px;
      color: var(--el-color-info);
    }
    
    p {
      margin: 0;
      font-size: 14px;
    }
  }
}
</style>